package com.t282.crm.web.controller;

import com.t282.crm.config.shiro.MyShiroRealm;
import com.t282.crm.entity.Right;
import com.t282.crm.entity.Role;
import com.t282.crm.entity.User;
import com.t282.crm.service.RoleService;
import com.t282.crm.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.subject.Subject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    //redis中数据的key的前缀
    private String SHIRO_LOGIN_COUNT = "shiro_login_count_";

    @PostMapping(value = "/doLogin")
    public String doLogin(String usrName, String usrPassword, HttpServletRequest request,Model model){
        /*User user = userService.login(usrName,usrPassword);
        if(user != null){
            request.getSession().setAttribute("user",user);
            return "redirect:/main";
        }else{
            request.setAttribute("msg","用户名或密码错误，登录失败");
            return "forward:/login";
        }*/
        try {

            //封装之前进行加密
            //usrPassword = userService.encryptPassword(usrPassword);

            UsernamePasswordToken token = new UsernamePasswordToken(usrName,usrPassword);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);   //认证，登录

            //认证(登录)成功，清空登录计数
            stringRedisTemplate.delete(SHIRO_LOGIN_COUNT+usrName);

            //认证(登录)成功
            User user = (User) subject.getPrincipal();

            //获取权限
            Role role = user.getRole(); //如果一对多关联不是立即加载，则需要通过用户获取角色
            List<Right> rights = roleService.findRightsByRole(role);
            role.getRights().addAll(rights);

            request.getSession().setAttribute("user",user);

            //清空权限缓存
            RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
            MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
            realm.clearMyCachedAuthorizationInfo();

            return "redirect:/main";
        }catch (UnknownAccountException | IncorrectCredentialsException e){
            model.addAttribute("msg","用户名或密码错误，登录失败！");
            return "forward:/login";
        }catch (LockedAccountException e){
            model.addAttribute("msg","用户被禁用，登录失败！");
            return "forward:/login";
        }catch (DisabledAccountException e){
            model.addAttribute("msg","账号1小时内禁止登录");
            return "forward:/login";
        }catch (AuthenticationException e){
            model.addAttribute("msg","认证异常，登录失败！");
            return "forward:/login";
        }
    }

    @GetMapping(value = "/logOut")
    public String logOut(HttpServletRequest request){
        request.getSession().removeAttribute("user");
        SecurityUtils.getSubject().logout();    //Shiro注销
        request.setAttribute("msg","用户已注销");
        return "forward:/login";    //建议重定向，保证删除Cookie
    }

    @RequestMapping(value = "/list")
    public String findList(String usrName,Long roleId,@RequestParam(value = "pageIndex",defaultValue = "1") Integer index, Model model){
        Sort sort = new Sort(Sort.Direction.DESC,"usrId");
        Pageable pageable = PageRequest.of(index-1,5,sort);
        Page<User> users = userService.findAllUsers(usrName,roleId,pageable);
        model.addAttribute("userList",users.getContent());
        model.addAttribute("totalElements",users.getTotalElements()); //总记录数
        model.addAttribute("totalPages",users.getTotalPages()); //总页数
        model.addAttribute("number",users.getNumber()+1);//当前页数
        model.addAttribute("usrName",usrName);
        model.addAttribute("roleId",roleId);
        return "/user/userlist";
    }

    @GetMapping(value = "/add")
    public String add(Model model){
        return "user/add";
    }

    @PostMapping(value = "/save")
    public String save(String usrName,String usrPassword,Long roleId,Long usrId,Integer usrFlag){
        User user = new User();
        user.setUsrName(usrName);
        user.setUsrPassword(userService.encryptPassword(usrPassword));

        Role role = new Role();
        role.setRoleId(roleId);
        user.setRole(role);
        user.setUsrFlag(usrFlag);
        if(usrId != null && usrId.longValue() != 0){
            user.setUsrId(usrId);
        }
        userService.addUser(user);

        //清空权限缓存
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAllCachedAuthorizationInfo();

        return "redirect:/user/list";
    }

    @GetMapping(value = "/edit")
    //@RequiresPermissions(value = "用户编辑")
    public String edit(Long usrId,Model model){
        User user = userService.getUser(usrId);
        model.addAttribute("user",user);
        model.addAttribute("roleId",user.getRole().getRoleId());
        model.addAttribute("usrId",usrId);
        model.addAttribute("usrFlag",user.getUsrFlag());
        return "user/edit";
    }

    @DeleteMapping(value = "/del")
    @ResponseBody
    public Map del(Long usrId){
        userService.deleteUser(usrId);
        Map map = new HashMap();
        map.put("delResult",true);
        return map;
    }
}
